<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Service Monitor</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3B82F6',
                        secondary: '#10B981',
                        danger: '#EF4444',
                        warning: '#F59E0B',
                        info: '#6366F1',
                        dark: '#1E293B',
                        light: '#F8FAFC'
                    },
                    fontFamily: {
                        inter: ['Inter', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .service-card {
                @apply bg-white rounded-lg shadow-md p-4 mb-4 transition-all duration-300 hover:shadow-lg;
            }
            .status-badge {
                @apply px-2 py-1 rounded-full text-xs font-semibold;
            }
            .btn {
                @apply px-4 py-2 rounded-md transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2;
            }
            .btn-primary {
                @apply bg-primary text-white hover:bg-primary/90 focus:ring-primary;
            }
            .btn-secondary {
                @apply bg-secondary text-white hover:bg-secondary/90 focus:ring-secondary;
            }
            .btn-danger {
                @apply bg-danger text-white hover:bg-danger/90 focus:ring-danger;
            }
            .btn-warning {
                @apply bg-warning text-white hover:bg-warning/90 focus:ring-warning;
            }
            .btn-outline {
                @apply border border-gray-300 hover:bg-gray-50 focus:ring-gray-300;
            }
            .form-input {
                @apply w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent;
            }
            .modal-backdrop {
                @apply fixed inset-0 bg-black/50 flex items-center justify-center z-50 opacity-0 pointer-events-none transition-opacity duration-300;
            }
            .modal-backdrop.active {
                @apply opacity-100 pointer-events-auto;
            }
            .modal-content {
                @apply bg-white rounded-lg shadow-xl max-w-md w-full mx-4 transform transition-transform duration-300 scale-95 opacity-0;
            }
            .modal-backdrop.active .modal-content {
                @apply scale-100 opacity-100;
            }
        }
    </style>
</head>

<body class="bg-gray-50 font-inter">
    <!-- 顶部导航 -->
    <header class="bg-white shadow-sm sticky top-0 z-40">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="flex justify-between h-16">
                <div class="flex items-center">
                    <i class="fa fa-server text-primary text-2xl mr-3"></i>
                    <h1 class="text-xl font-bold text-gray-900">Service Monitor</h1>
                </div>
                <div class="flex items-center">
                    <button id="addServiceBtn" class="btn btn-primary flex items-center">
                        <i class="fa fa-plus mr-2"></i> Add Service
                    </button>
                </div>
            </div>
        </div>
    </header>

    <!-- 主要内容 -->
    <main class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
        <!-- 状态概览卡片 -->
        <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
            <div class="bg-white rounded-lg shadow p-6">
                <div class="flex items-center">
                    <div class="flex-shrink-0 bg-blue-100 p-3 rounded-full">
                        <i class="fa fa-server text-primary text-xl"></i>
                    </div>
                    <div class="ml-5 w-0 flex-1">
                        <dl>
                            <dt class="text-sm font-medium text-gray-500 truncate">Total Services</dt>
                            <dd>
                                <div class="text-lg font-semibold text-gray-900" id="totalServices">0</div>
                            </dd>
                        </dl>
                    </div>
                </div>
            </div>
            <div class="bg-white rounded-lg shadow p-6">
                <div class="flex items-center">
                    <div class="flex-shrink-0 bg-green-100 p-3 rounded-full">
                        <i class="fa fa-check-circle text-secondary text-xl"></i>
                    </div>
                    <div class="ml-5 w-0 flex-1">
                        <dl>
                            <dt class="text-sm font-medium text-gray-500 truncate">Running</dt>
                            <dd>
                                <div class="text-lg font-semibold text-gray-900" id="runningServices">0</div>
                            </dd>
                        </dl>
                    </div>
                </div>
            </div>
            <div class="bg-white rounded-lg shadow p-6">
                <div class="flex items-center">
                    <div class="flex-shrink-0 bg-red-100 p-3 rounded-full">
                        <i class="fa fa-stop-circle text-danger text-xl"></i>
                    </div>
                    <div class="ml-5 w-0 flex-1">
                        <dl>
                            <dt class="text-sm font-medium text-gray-500 truncate">Stopped</dt>
                            <dd>
                                <div class="text-lg font-semibold text-gray-900" id="stoppedServices">0</div>
                            </dd>
                        </dl>
                    </div>
                </div>
            </div>
        </div>

        <!-- 服务列表 -->
        <div class="bg-white shadow rounded-lg overflow-hidden">
            <div class="px-4 py-5 sm:px-6 border-b border-gray-200">
                <h2 class="text-lg font-semibold text-gray-900">Service List</h2>
            </div>
            <div class="px-4 py-5 sm:p-6">
                <div class="flex flex-col">
                    <div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
                        <div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
                            <div class="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
                                <table class="min-w-full divide-y divide-gray-200">
                                    <thead class="bg-gray-50">
                                        <tr>
                                            <th scope="col"
                                                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                                Name</th>
                                            <th scope="col"
                                                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                                Description</th>
                                            <th scope="col"
                                                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                                Status</th>
                                            <th scope="col"
                                                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                                Last Updated</th>
                                            <th scope="col"
                                                class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
                                                Actions</th>
                                        </tr>
                                    </thead>
                                    <tbody class="bg-white divide-y divide-gray-200" id="serviceList">
                                        <!-- 服务列表将通过JavaScript动态填充 -->
                                        <tr>
                                            <td colspan="5" class="px-6 py-10 text-center text-gray-500">
                                                <div class="flex flex-col items-center">
                                                    <i class="fa fa-spinner fa-spin text-3xl mb-3"></i>
                                                    <p>Loading services...</p>
                                                </div>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </main>

    <!-- 添加服务模态框 -->
    <div id="addServiceModal" class="modal-backdrop">
        <div class="modal-content">
            <div class="px-6 py-4 border-b border-gray-200">
                <div class="flex justify-between items-center">
                    <h3 class="text-lg font-medium text-gray-900">Add New Service</h3>
                    <button id="closeAddModalBtn" class="text-gray-400 hover:text-gray-500 focus:outline-none">
                        <i class="fa fa-times"></i>
                    </button>
                </div>
            </div>
            <div class="px-6 py-4">
                <form id="addServiceForm">
                    <div class="mb-4">
                        <label for="serviceName" class="block text-sm font-medium text-gray-700 mb-1">Service
                            Name</label>
                        <input type="text" id="serviceName" class="form-input" placeholder="Enter service name"
                            required>
                    </div>
                    <div class="mb-4">
                        <label for="serviceDescription"
                            class="block text-sm font-medium text-gray-700 mb-1">Description</label>
                        <textarea id="serviceDescription" class="form-input" rows="3"
                            placeholder="Enter service description"></textarea>
                    </div>
                    <div class="flex justify-end">
                        <button type="button" id="cancelAddServiceBtn" class="btn btn-outline mr-2">Cancel</button>
                        <button type="submit" class="btn btn-primary">Add Service</button>
                    </div>
                </form>
            </div>
        </div>
    </div>

    <!-- 更新服务模态框 -->
    <div id="updateServiceModal" class="modal-backdrop">
        <div class="modal-content">
            <div class="px-6 py-4 border-b border-gray-200">
                <div class="flex justify-between items-center">
                    <h3 class="text-lg font-medium text-gray-900">Update Service</h3>
                    <button id="closeUpdateModalBtn" class="text-gray-400 hover:text-gray-500 focus:outline-none">
                        <i class="fa fa-times"></i>
                    </button>
                </div>
            </div>
            <div class="px-6 py-4">
                <form id="updateServiceForm">
                    <input type="hidden" id="updateServiceId">
                    <div class="mb-4">
                        <label for="updateServiceName" class="block text-sm font-medium text-gray-700 mb-1">Service
                            Name</label>
                        <input type="text" id="updateServiceName" class="form-input" placeholder="Enter service name"
                            required>
                    </div>
                    <div class="mb-4">
                        <label for="updateServiceDescription"
                            class="block text-sm font-medium text-gray-700 mb-1">Description</label>
                        <textarea id="updateServiceDescription" class="form-input" rows="3"
                            placeholder="Enter service description"></textarea>
                    </div>
                    <div class="flex justify-end">
                        <button type="button" id="cancelUpdateServiceBtn" class="btn btn-outline mr-2">Cancel</button>
                        <button type="submit" class="btn btn-primary">Update Service</button>
                    </div>
                </form>
            </div>
        </div>
    </div>

    <!-- 通知提示 -->
    <div id="notification"
        class="fixed top-4 right-4 bg-white rounded-lg shadow-lg p-4 transform translate-x-full transition-transform duration-300 z-50 flex items-center">
        <div id="notificationIcon" class="mr-3 p-2 rounded-full bg-green-100">
            <i class="fa fa-check text-secondary"></i>
        </div>
        <div>
            <p id="notificationMessage" class="text-sm font-medium text-gray-900">Operation successful!</p>
        </div>
        <button id="closeNotificationBtn" class="ml-4 text-gray-400 hover:text-gray-500 focus:outline-none">
            <i class="fa fa-times"></i>
        </button>
    </div>

    <script>
        // 状态样式映射
        const statusStyles = {
            'Running': 'bg-green-100 text-green-800',
            'Stopped': 'bg-gray-100 text-gray-800',
            'Starting': 'bg-blue-100 text-blue-800',
            'Stopping': 'bg-yellow-100 text-yellow-800',
            'Error': 'bg-red-100 text-red-800'
        };

        // 状态图标映射
        const statusIcons = {
            'Running': 'fa-check-circle',
            'Stopped': 'fa-stop-circle',
            'Starting': 'fa-spinner fa-spin',
            'Stopping': 'fa-spinner fa-spin',
            'Error': 'fa-exclamation-circle'
        };

        // DOM元素
        const serviceListEl = document.getElementById('serviceList');
        const totalServicesEl = document.getElementById('totalServices');
        const runningServicesEl = document.getElementById('runningServices');
        const stoppedServicesEl = document.getElementById('stoppedServices');
        const addServiceBtn = document.getElementById('addServiceBtn');
        const addServiceModal = document.getElementById('addServiceModal');
        const closeAddModalBtn = document.getElementById('closeAddModalBtn');
        const cancelAddServiceBtn = document.getElementById('cancelAddServiceBtn');
        const addServiceForm = document.getElementById('addServiceForm');
        const updateServiceModal = document.getElementById('updateServiceModal');
        const closeUpdateModalBtn = document.getElementById('closeUpdateModalBtn');
        const cancelUpdateServiceBtn = document.getElementById('cancelUpdateServiceBtn');
        const updateServiceForm = document.getElementById('updateServiceForm');
        const notification = document.getElementById('notification');
        const notificationMessage = document.getElementById('notificationMessage');
        const closeNotificationBtn = document.getElementById('closeNotificationBtn');

        // 模拟服务数据
        let mockServices = [
            { id: 1, name: 'Web Server', description: 'Hosts the main website', status: 'Running', lastUpdated: '2025-05-19 10:30:45' },
            { id: 2, name: 'Database', description: 'MySQL database server', status: 'Running', lastUpdated: '2025-05-19 10:31:22' },
            { id: 3, name: 'API Gateway', description: 'Manages API requests', status: 'Stopped', lastUpdated: '2025-05-19 10:25:18' },
            { id: 4, name: 'Cache Server', description: 'Redis caching service', status: 'Running', lastUpdated: '2025-05-19 10:32:05' },
            { id: 5, name: 'Message Queue', description: 'RabbitMQ message broker', status: 'Error', lastUpdated: '2025-05-19 10:20:30' }
        ];

        // 显示通知
        function showNotification(message, isSuccess = true) {
            notificationMessage.textContent = message;
            const notificationIcon = document.getElementById('notificationIcon');

            if (isSuccess) {
                notificationIcon.className = 'mr-3 p-2 rounded-full bg-green-100';
                notificationIcon.innerHTML = '<i class="fa fa-check text-secondary"></i>';
            } else {
                notificationIcon.className = 'mr-3 p-2 rounded-full bg-red-100';
                notificationIcon.innerHTML = '<i class="fa fa-exclamation text-danger"></i>';
            }

            notification.classList.remove('translate-x-full');

            // 3秒后自动关闭
            setTimeout(() => {
                notification.classList.add('translate-x-full');
            }, 3000);
        }

        // 获取服务列表（模拟）
        async function fetchServices() {
            // 模拟网络请求延迟
            await new Promise(resolve => setTimeout(resolve, 500));

            // 随机更新部分服务状态，模拟实时变化
            mockServices = mockServices.map(service => {
                if (Math.random() > 0.8) {
                    const statuses = ['Running', 'Stopped', 'Starting', 'Stopping', 'Error'];
                    return {
                        ...service,
                        status: statuses[Math.floor(Math.random() * statuses.length)],
                        lastUpdated: new Date().toISOString().slice(0, 19).replace('T', ' ')
                    };
                }
                return service;
            });

            return mockServices;
        }

        // 渲染服务列表
        function renderServices(services) {
            serviceListEl.innerHTML = '';

            if (services.length === 0) {
                serviceListEl.innerHTML = `
                    <tr>
                        <td colspan="5" class="px-6 py-10 text-center text-gray-500">
                            <div class="flex flex-col items-center">
                                <i class="fa fa-folder-open text-3xl mb-3"></i>
                                <p>No services found. Click "Add Service" to create one.</p>
                            </div>
                        </td>
                    </tr>
                `;
                return;
            }

            services.forEach(service => {
                const statusClass = statusStyles[service.status] || 'bg-gray-100 text-gray-800';
                const statusIcon = statusIcons[service.status] || 'fa-question-circle';

                const row = document.createElement('tr');
                row.className = 'hover:bg-gray-50 transition-colors duration-150';
                row.innerHTML = `
                    <td class="px-6 py-4 whitespace-nowrap">
                        <div class="flex items-center">
                            <div class="flex-shrink-0 h-10 w-10 bg-primary/10 rounded-full flex items-center justify-center">
                                <i class="fa fa-server text-primary"></i>
                            </div>
                            <div class="ml-4">
                                <div class="text-sm font-medium text-gray-900">${service.name}</div>
                                <div class="text-xs text-gray-500">ID: ${service.id}</div>
                            </div>
                        </div>
                    </td>
                    <td class="px-6 py-4">
                        <div class="text-sm text-gray-900">${service.description}</div>
                    </td>
                    <td class="px-6 py-4 whitespace-nowrap">
                        <span class="status-badge ${statusClass}">
                            <i class="fa ${statusIcon} mr-1"></i> ${service.status}
                        </span>
                    </td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                        ${service.lastUpdated}
                    </td>
                    <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
                        ${service.status === 'Running' ?
                        `<button data-id="${service.id}" class="stop-btn text-blue-600 hover:text-blue-900 mr-3 transition-colors duration-150">
                                <i class="fa fa-stop mr-1"></i> Stop
                            </button>` :
                        `<button data-id="${service.id}" class="start-btn text-green-600 hover:text-green-900 mr-3 transition-colors duration-150">
                                <i class="fa fa-play mr-1"></i> Start
                            </button>`
                    }
                        <button data-id="${service.id}" data-name="${service.name}" data-description="${service.description}" class="update-btn text-yellow-600 hover:text-yellow-900 mr-3 transition-colors duration-150">
                            <i class="fa fa-edit mr-1"></i> Edit
                        </button>
                        <button data-id="${service.id}" class="delete-btn text-red-600 hover:text-red-900 transition-colors duration-150">
                            <i class="fa fa-trash mr-1"></i> Delete
                        </button>
                    </td>
                `;

                serviceListEl.appendChild(row);
            });

            // 添加事件监听器
            document.querySelectorAll('.start-btn').forEach(btn => {
                btn.addEventListener('click', () => startService(btn.dataset.id));
            });

            document.querySelectorAll('.stop-btn').forEach(btn => {
                btn.addEventListener('click', () => stopService(btn.dataset.id));
            });

            document.querySelectorAll('.update-btn').forEach(btn => {
                btn.addEventListener('click', () => openUpdateModal(btn.dataset.id, btn.dataset.name, btn.dataset.description));
            });

            document.querySelectorAll('.delete-btn').forEach(btn => {
                btn.addEventListener('click', () => deleteService(btn.dataset.id));
            });
        }

        // 更新统计信息
        function updateStats(services) {
            totalServicesEl.textContent = services.length;

            const runningCount = services.filter(service => service.status === 'Running').length;
            runningServicesEl.textContent = runningCount;

            const stoppedCount = services.filter(service => service.status === 'Stopped' || service.status === 'Error').length;
            stoppedServicesEl.textContent = stoppedCount;
        }

        // 刷新服务列表
        async function refreshServices() {
            try {
                const services = await fetchServices();
                renderServices(services);
                updateStats(services);
            } catch (error) {
                console.error('Error refreshing services:', error);
                showNotification('Failed to refresh services', false);
            }
        }

        // 启动服务（模拟）
        async function startService(id) {
            try {
                // 模拟API调用延迟
                await new Promise(resolve => setTimeout(resolve, 800));

                // 更新服务状态
                mockServices = mockServices.map(service => {
                    if (service.id === parseInt(id)) {
                        return { ...service, status: 'Starting' };
                    }
                    return service;
                });

                // 模拟启动过程
                await new Promise(resolve => setTimeout(resolve, 1500));

                mockServices = mockServices.map(service => {
                    if (service.id === parseInt(id)) {
                        return {
                            ...service,
                            status: 'Running',
                            lastUpdated: new Date().toISOString().slice(0, 19).replace('T', ' ')
                        };
                    }
                    return service;
                });

                showNotification('Service started successfully');
                await refreshServices();
            } catch (error) {
                console.error('Error starting service:', error);
                showNotification('Failed to start service', false);
            }
        }

        // 停止服务（模拟）
        async function stopService(id) {
            try {
                // 模拟API调用延迟
                await new Promise(resolve => setTimeout(resolve, 800));

                // 更新服务状态
                mockServices = mockServices.map(service => {
                    if (service.id === parseInt(id)) {
                        return { ...service, status: 'Stopping' };
                    }
                    return service;
                });

                // 模拟停止过程
                await new Promise(resolve => setTimeout(resolve, 1500));

                mockServices = mockServices.map(service => {
                    if (service.id === parseInt(id)) {
                        return {
                            ...service,
                            status: 'Stopped',
                            lastUpdated: new Date().toISOString().slice(0, 19).replace('T', ' ')
                        };
                    }
                    return service;
                });

                showNotification('Service stopped successfully');
                await refreshServices();
            } catch (error) {
                console.error('Error stopping service:', error);
                showNotification('Failed to stop service', false);
            }
        }

        // 更新服务（模拟）
        async function updateService(id, name, description) {
            try {
                // 模拟API调用延迟
                await new Promise(resolve => setTimeout(resolve, 500));

                // 更新服务数据
                mockServices = mockServices.map(service => {
                    if (service.id === parseInt(id)) {
                        return {
                            ...service,
                            name,
                            description,
                            lastUpdated: new Date().toISOString().slice(0, 19).replace('T', ' ')
                        };
                    }
                    return service;
                });

                showNotification('Service updated successfully');
                updateServiceModal.classList.remove('active');
                await refreshServices();
            } catch (error) {
                console.error('Error updating service:', error);
                showNotification('Failed to update service', false);
            }
        }

        // 添加服务（模拟）
        async function addNewService(name, description) {
            try {
                // 模拟API调用延迟
                await new Promise(resolve => setTimeout(resolve, 500));

                // 生成新服务ID
                const newId = Math.max(0, ...mockServices.map(s => s.id)) + 1;

                // 添加新服务
                mockServices.push({
                    id: newId,
                    name,
                    description,
                    status: 'Stopped',
                    lastUpdated: new Date().toISOString().slice(0, 19).replace('T', ' ')
                });

                showNotification('Service added successfully');
                addServiceModal.classList.remove('active');
                addServiceForm.reset();
                await refreshServices();
            } catch (error) {
                console.error('Error adding service:', error);
                showNotification('Failed to add service', false);
            }
        }

        // 删除服务（模拟）
        async function deleteService(id) {
            if (confirm('Are you sure you want to delete this service?')) {
                try {
                    // 模拟API调用延迟
                    await new Promise(resolve => setTimeout(resolve, 500));

                    // 删除服务
                    mockServices = mockServices.filter(service => service.id !== parseInt(id));

                    showNotification('Service deleted successfully');
                    await refreshServices();
                } catch (error) {
                    console.error('Error deleting service:', error);
                    showNotification('Failed to delete service', false);
                }
            }
        }

        // 打开添加模态框
        function openAddModal() {
            addServiceModal.classList.add('active');
        }

        // 关闭添加模态框
        function closeAddModal() {
            addServiceModal.classList.remove('active');
        }

        // 打开更新模态框
        function openUpdateModal(id, name, description) {
            document.getElementById('updateServiceId').value = id;
            document.getElementById('updateServiceName').value = name;
            document.getElementById('updateServiceDescription').value = description;
            updateServiceModal.classList.add('active');
        }

        // 关闭更新模态框
        function closeUpdateModal() {
            updateServiceModal.classList.remove('active');
        }

        // 关闭通知
        function closeNotification() {
            notification.classList.add('translate-x-full');
        }

        // 事件监听器
        addServiceBtn.addEventListener('click', openAddModal);
        closeAddModalBtn.addEventListener('click', closeAddModal);
        cancelAddServiceBtn.addEventListener('click', closeAddModal);
        addServiceForm.addEventListener('submit', (e) => {
            e.preventDefault();
            const name = document.getElementById('serviceName').value;
            const description = document.getElementById('serviceDescription').value;
            addNewService(name, description);
        });

        closeUpdateModalBtn.addEventListener('click', closeUpdateModal);
        cancelUpdateServiceBtn.addEventListener('click', closeUpdateModal);
        updateServiceForm.addEventListener('submit', (e) => {
            e.preventDefault();
            const id = document.getElementById('updateServiceId').value;
            const name = document.getElementById('updateServiceName').value;
            const description = document.getElementById('updateServiceDescription').value;
            updateService(id, name, description);
        });

        closeNotificationBtn.addEventListener('click', closeNotification);

        // 初始化
        document.addEventListener('DOMContentLoaded', async () => {
            await refreshServices();

            // 定时刷新服务列表
            setInterval(refreshServices, 5000);
        });
    </script>
</body>

</html>